using UnityEngine;
using System.Collections.Generic;

public class Zombie : Character
{
	private Interactive savedObject;
	private List<Tile> savedPath;

	protected override void StartAction()
	{
		base.StartAction();

		Invoke("ChooseAction", 0.5f);
	}

	private void ChooseAction()
	{
		Debug.Log("ChooseAction " + this);
		Dictionary<Interactive, List<Tile>> players = FloorManager.Instance.InteractivesInArea(walkArea, ActionType.Attack_Player);
		// Attack player
		if (players.Count > 0)
		{
			AttackPlayer(players);
		}
		else
		{
			MoveCloser();
		}
	}

	private void AttackPlayer(Dictionary<Interactive, List<Tile>> _players)
	{
		Interactive closest = Tile.ClosestInteractive(currentTile, new List<Interactive>(_players.Keys));
		if (closest != null)
		{
			savedPath = Search.GetPath(currentTile, _players[closest][0], walkArea);
			savedObject = closest;
			savedObject.SetAsSelectable(savedPath);
			AreaCreator.ActivatePath(savedPath, Tile.State.Attack, AttackPlayerCallback);
		}
	}

	private void MoveCloser()
	{
		Interactive closest = Tile.ClosestInteractive(currentTile, FloorManager.Instance.GetInteractives<Player>());
		
		List<Tile> path = Search.GetPath(currentTile, closest.currentTile, null, (uint)Area.RemoveType.Characters);

		int speed = (int)GetInfo<CharacterInfo>().speed.minValue;
		Interactive blocker = TrimPath(ref path, speed);
		if (path.Count == 0)
		{
			FinishAction();
		}
		else if (blocker == null)
		{
			savedPath = path;
			AreaCreator.ActivatePath(path, Tile.State.Walk, FollowPathCallback);
		}
		else
		{
			savedObject = blocker;
			savedObject.SetAsSelectable(path);
			AreaCreator.ActivatePath(path, Tile.State.PickUp, PickupObjectCallback);
		}
	}

	private Interactive TrimPath(ref List<Tile> _path, int _speed)
	{
		if (_path.Count > _speed)
		{
			_path.RemoveAt(0);
			_path.RemoveRange(_speed, _path.Count - _speed);
		}

		// Remove tiles that are separated by a door
		for (int i = 0; i < _path.Count - 1; i++)
		{
			if (!_path[i].IsConnectionOpen(_path[i + 1]))
			{
				Debug.Log("Remove Range " + i + _path.Count);
				_path.RemoveRange(i, _path.Count - i);
				break;
			}
		}

		foreach (Tile tile in _path)
		{
			if (tile.objectOnTop != null && tile.objectOnTop is Useable)
			{
				return tile.objectOnTop;
			}
		}

		return null;
	}

	private void AttackPlayerCallback()
	{
		PerformAttack(savedObject as Character, StatBody.RandomBodyType(), savedPath);
	}
	
	private void FollowPathCallback()
	{
		FollowPath(savedPath);
	}

	private void PickupObjectCallback()
	{
		savedObject.InteractiveClicked();
	}
	
	public override void InteractiveClicked()
	{
		GameObject popup = ScreensManager.Instance.ShowPopup(PopupID.Popup_Attack);
		popup.GetComponent<AttackPopup>().Init(this, pathForInteraction);
	}
	
	protected override void FingerClick()
	{
		GameWidget.ShowWidget(this, WidgetID.Widget_Zombie);
	}
}
